Linux中eventfd的使用
eventfd简介
eventfd是用来实现多进程或多线程之间的事件通知的,常见的事件通知机制除了eventfd外,还有条件变量和管道等 方式。
条件变量必须和互斥锁相结合使用,使用起来较麻烦,并且条件变量不能像eventfd一样为I/O事件驱动。
管道可以和I/O复用很好的融合,但是管道比eventfd多用了一个文件描述符,而且 管道内核还得给其管理的缓冲区,eventfd则不需要。
event的主要接口
eventfd的接口形式如下:
1
| int eventfd(unsigned int initval, int flags);
|
eventfd()创建一个文件描述符,这个文件描述符用户可以通过等待其可读来实现事件通知,该通知靠内核来响应用户空间的应用事件。上述接口的第一个参数是由内核来保持的64位计数器,这个计算器由参数initval来初始化,一般设为0。
第二个参数flags可以为EFD_NONBLOCK或EFD_CLOEXEC。
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include <sys/eventfd.h> #include <stdio.h> #include <pthread.h> #include <unistd.h> int fd; uint64_t buffer; void threadFunc(void) { int t; while (1) { t = read(fd, &buffer, sizeof(buffer)); if (sizeof(buffer) < 8) { printf("buffer错误\n"); } printf("t = %11u buffer = %11u\n", t, buffer); if (t == 8) { printf("唤醒成功\n"); } } } int main() { uint64_t buf = 1; int ret; pthread_t tid; if ((fd = eventfd(0, 0)) == -1) { printf("创建失败\n"); } if (pthread_create(&tid, NULL, threadFunc, NULL) < 0) { printf("线程创建失败\n"); } while (1) { ret = write(fd, &buf, sizeof(buf)); if (ret != 8) { printf("写错误\n"); } sleep(2); } return 0; }
|